package test;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
;

public class writeJSON {
	public String pathname;
	public String[] filenames;
	public int fileCount;
	private int totalCount;
	public String[] segID;
	public int segIDCount;
	public String[] segm;
	public String[] bbox;

	public String createSegmfromBbox(int minX, int minY, int maxX, int maxY) {
		String pointFormat = "\"%d, %d\"";
		String A = String.format(pointFormat, minX, minY);
		String B = String.format(pointFormat, maxX, minY);
		String C = String.format(pointFormat, maxX, maxY);
		String D = String.format(pointFormat, minX, maxY);
		return A + "," + B + "," + C + "," + D + "," + A;
	}

	public String createBbox(int minX, int minY, int maxX, int maxY) {
		String A = "\"MaxX\":" + maxX;
		String B = "\"MaxY\":" + maxY;
		String C = "\"MinX\":" + minX;
		String D = "\"MinY\":" + minY;
		return A + "," + B + "," + C + "," + D;
	}

	public double same_area(int[] rect1, int[] rect2) {

		double sArea = 0;
		for (int x = rect1[0]; x < rect1[2]; x++) {
			for (int y = rect1[1]; y < rect1[3]; y++) {
				if (x >= rect2[0] && x <= rect2[2]) {
					if (y >= rect2[1] && y <= rect2[3])
						sArea += 1.0;
				}
			}
		}
		return sArea;
	}

	public double area(int[] rect) {
		return (rect[2] - rect[0]) * (rect[3] - rect[1]);
	}

	public void outputOneImageJSON(int n) {
		String filenameFormat = "\"filename\":\"%s\"";
		// String widthFormat = "\"width\":%d"; //不需要输出
		// String heightFormat = "\"height\":%d"; //不需要输出
		String productsFormat = "\"products\":[%s]";
		String categoryFormat = "\"category\":\"%s\"";
		String segmFormat = "\"segm\":[%s]";
		String bboxFormat = "\"bbox\":{%s}";

		try {
			BufferedReader br = new BufferedReader(new FileReader(this.pathname + this.filenames[n] + ".txt"));
			String data = br.readLine(); // read the 1st line
			if (data == null || data.length() < 1) {
				return;
			}
			Scanner sc = new Scanner(data);
			int productCount = Integer.parseInt(sc.next());
			int[][] rect = new int[productCount][4];
			double[] rectScore = new double[productCount];
			String[] cate = new String[productCount];
			String product = "";
			for (int i = 0; i < productCount; i++) {
				data = br.readLine();
				sc = new Scanner(data);
				String category = String.format(categoryFormat, sc.next());
				cate[i] = new String(category);
				int minX = Integer.parseInt(sc.next());
				int minY = Integer.parseInt(sc.next());
				int maxX = Integer.parseInt(sc.next());
				int maxY = Integer.parseInt(sc.next());
				double scoreF = Double.parseDouble(sc.next());
				rect[i][0] = minX;
				rect[i][1] = minY;
				rect[i][2] = maxX;
				rect[i][3] = maxY;
				rectScore[i] = scoreF;
			}
			boolean[] keep = new boolean[productCount];
			/*
			 * *** this part below remove overlapping rectangles (overlapping
			 * area / each > 0.8 for both
			 */
			for (int i = 0; i < productCount; i++)
				keep[i] = true;
			for (int i = 0; i < productCount - 1; i++) {
				double areaI = area(rect[i]);
				for (int j = i + 1; j < productCount; j++) {
					double sameArea = same_area(rect[i], rect[j]);
					double areaJ = area(rect[j]);
					if (sameArea / areaI > 0.8 && sameArea / areaJ > 0.8) { // 重叠区域
																			// /单个矩形
																			// 都要超过80%
						if (rectScore[i] > rectScore[j])
							keep[j] = false;
						// score 小的不输出。 如果不需要删除重复区域，
						// 将false改成true，所有结果（矩形区域）都会输出到JSON
					}
				}
			}
			// 最后一个的输出格式不同（没有"," 等）需要记下最后一个的编号
			int lastCorrect = -1;
			for (int i = 0; i < productCount; i++) {
				if (keep[i])
					lastCorrect = i;
			}
			/* *** the part ends here */
			for (int i = 0; i < productCount; i++) {
				String segm = null;
				String bbox = null;
				if (!keep[i])
					continue;
				if (this.segIDCount != 0) {
					// !this.segm[totalCount].equals("")
					segm = String.format(segmFormat, this.segm[totalCount]);
					bbox = String.format(bboxFormat, this.bbox[totalCount]);
				} else {
					segm = String
							.format(segmFormat, createSegmfromBbox(rect[i][0], rect[i][1], rect[i][2], rect[i][3]));
					bbox = String.format(bboxFormat, createBbox(rect[i][0], rect[i][1], rect[i][2], rect[i][3]));
				}
				totalCount++;
				if (i != lastCorrect)
					product = product + "{" + cate[i] + "," + segm + "," + bbox + "},";
				else
					product = product + "{" + cate[i] + "," + segm + "," + bbox + "}";
			}
			String products = String.format(productsFormat, product);
			br.close();
			System.out.print(String.format(filenameFormat, filenames[n]) + "," + products);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void prepareSegmBbox(String filename) {
		this.segID = new String[10000];
		this.segm = new String[10000];
		this.bbox = new String[10000];
		this.segIDCount = 0;
		try {
			BufferedReader br = new BufferedReader(new FileReader(filename));
			// String data = br.readLine(); // read the 1st line
			String data = null;
			do {
				data = br.readLine(); // 一次读入一行，直到null为文件结束
				if (data == null)
					break;
				if (data.length() < 2)
					break;
				Scanner sc = new Scanner(data);
				this.segID[this.segIDCount] = sc.next();
				this.segm[this.segIDCount] = "";
				this.bbox[this.segIDCount] = "";
				int num = Integer.parseInt(sc.next());
				int minX = 10000;
				int minY = 10000;
				int maxX = 0;
				int maxY = 0;
				for (int i = 0; i < num; i++) {
					data = br.readLine();
					sc = new Scanner(data);
					int X = Integer.parseInt(sc.next());
					int Y = Integer.parseInt(sc.next());
					this.segm[this.segIDCount] += String.format("\"%d, %d\"", X, Y);
					if (i != num - 1)
						this.segm[this.segIDCount] += ",";
					if (X < minX)
						minX = X;
					if (X > maxX)
						maxX = X;
					if (Y < minY)
						minY = Y;
					if (Y > maxY)
						maxY = Y;
				}
				if (num != 0)
					this.bbox[this.segIDCount] += String.format("\"MaxX\":%d,\"MaxY\":%d,\"MinX\":%d,\"MinY\":%d",
							maxX, maxY, minX, minY);
				this.segIDCount++;
			} while (true);
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void createFilelist(String path) {
		this.segID = null;
		this.segIDCount = 0;
		File dir = new File(path);
		ArrayList<String> arrList = new ArrayList<String>();
		String[] tmpList = dir.list();
		Arrays.sort(tmpList);
		for (String filename : tmpList) {
			if (filename.endsWith(".txt"))
				arrList.add(filename.substring(0, filename.length() - 4));
		}
		this.filenames = new String[arrList.size()];
		arrList.toArray(this.filenames);
		this.fileCount = this.filenames.length;

	}

	public writeJSON(String path) {
		this.pathname = path;
		this.fileCount = 0;
		this.totalCount = 0;
		createFilelist(path);
		System.out.print("[");
		boolean[] non_empty_file = new boolean[fileCount];
		int lastNonEmptyFile = 0;
		for (int i = 0; i < fileCount; i++)
			if (new File(this.pathname + this.filenames[i] + ".txt").length() < 3) {
				// if file data < 3 bytes, consider it as empty file.
				non_empty_file[i] = false;
			} else {
				non_empty_file[i] = true;
				if (i > lastNonEmptyFile)
					lastNonEmptyFile = i;
			}
		for (int i = 0; i < fileCount; i++) {
			if (non_empty_file[i]) {
				System.out.print("{");
				outputOneImageJSON(i);
				if (i != lastNonEmptyFile)
					System.out.print("},");
				else
					System.out.print("}");
			}
		}
		System.out.println("]");
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// new outputJSON("D:/TDDownload/JPEGImages/result/","list.txt");
		String path = "./";
		if (args.length > 0)
			path = args[0];
		if (!(path.endsWith("/") || path.endsWith("\\"))) {
			if (path.indexOf('/') != -1)
				path = path + "/";
			else
				path = path + "\\";
		}
		if (args.length == 1)
			new writeJSON(path);
		else
			System.out.println("Usage: java -jar BOT2WriteJSON result_folder");
	}
}
